package com.zhuanzhuan.hero.user.util;

import com.bj58.youpin.common.rpc.result.Result;
import com.bj58.zhuanzhuan.zzentry.common.service.entity.ZZOpenScfBaseResult;
import com.google.common.base.Strings;
import com.zhuanzhuan.hero.biz.common.util.WxWarnTemplateUtil;
import com.zhuanzhuan.hero.user.consts.Consts;
import lombok.extern.slf4j.Slf4j;

import java.util.function.Function;

/**
 * @author jiazebiao
 * @date 2024/7/11
 * @description rpc util
 */
@Slf4j
public class RpcUtil {
    public static <T> T extractResult(Result<T> result, Object... params){
        if(result == null || !result.isSuccess()){
            String invokePath = getInvokePath(Thread.currentThread().getStackTrace());
            logErr(invokePath, result, params);
            WxWarnTemplateUtil.warnOutService(Consts.SERVICE_NAME, "Scf接口调用失败");
            return null;
        }
        return result.getData();
    }

    private static void logErr(String path, Object result, Object... params){
        if(params == null || params.length == 0){
            log.error("rpc请求失败， path:{}, result:{}", path, result);
        }else{
            Object[] objs = new Object[( params.length) + 2];
            objs[0] = path;
            System.arraycopy(params, 0, objs, 1, params.length);
            objs[objs.length -1] = result;
            log.error("rpc请求失败，path:{}, request:" + Strings.repeat("{},", params.length) + "result:{}", objs);
        }
    }
    public static <T> T extractResult(ZZOpenScfBaseResult<T> result, Object... params){
        if(result == null || !result.isSuccess()){
            String invokePath = getInvokePath(Thread.currentThread().getStackTrace());
            logErr(invokePath, result, params);
            return null;
        }
        return result.getData();
    }

    /**
     * 返回实体转换
     * @param result
     * @return
     * @param <S>
     * @param <R>
     */
    public static <S,R> ZZOpenScfBaseResult<S> buildScfResult(ZZOpenScfBaseResult<R> result,Object... params){
        String invokePath = getInvokePath(Thread.currentThread().getStackTrace());
        return buildScfResult(result, invokePath, null, params);
    }

    /**
     * 返回实体转换
     * @param result
     * @param dataTransFun
     * @return
     * @param <S>
     * @param <R>
     */
    public static <S,R> ZZOpenScfBaseResult<S> buildScfResult(Result<R> result, Function<R, S> dataTransFun){
        ZZOpenScfBaseResult<S> scfResult = new ZZOpenScfBaseResult<>();
        scfResult.setCode(result.getCode());
        if(dataTransFun != null && result.getData() != null){
            scfResult.setData(dataTransFun.apply(result.getData()));
        }
        scfResult.setErrorMsg(result.getMsg());
        return scfResult;
    }

    /**
     * 返回实体转换
     * @param result
     * @param dataTransFun
     * @return
     * @param <S>
     * @param <R>
     */
    private static <S,R> ZZOpenScfBaseResult<S> buildScfResult(ZZOpenScfBaseResult<R> result, String path, Function<R, S> dataTransFun, Object... params){
        ZZOpenScfBaseResult<S> scfResult = new ZZOpenScfBaseResult<>();
        if(result.getCode() != 0){
            logErr(path, result, params);
            scfResult.setCode(-1);
            scfResult.setErrorMsg(result.getErrorMsg());
            return scfResult;
        }
        scfResult.setCode(0);
        if(dataTransFun != null && result.getData() != null){
            scfResult.setData(dataTransFun.apply(result.getData()));
        }
        return scfResult;
    }

    private static String getInvokePath(StackTraceElement[] stackTrace){
        StackTraceElement stackTraceElement = stackTrace[2];
        return stackTraceElement.getClassName() + "#" + stackTraceElement.getMethodName() + ":" + stackTraceElement.getLineNumber();
    }
}